package com.haiyi.controller;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.haiyi.drools.DroolsStream;
import com.haiyi.drools.DroolsUtil;
import com.haiyi.entity.AiaModelForm;
import com.haiyi.entity.AiaUser;
import com.haiyi.entity.Role;
import com.haiyi.service.AiaFormService;
import com.haiyi.service.RoleService;
import org.activiti.engine.*;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p> </p>
 *
 * <pre> Created: 2018/11/28 15:24 </pre>
 *
 * @author hlu
 * @version 1.0
 * @since JDK 1.7
 */
@RestController
public class ActivitiController {

    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private IdentityService identityService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private AiaFormService formService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private RoleService roleService;


    private String processInstanceId;

    @GetMapping("/start")
    public boolean start(HttpSession session){
        final AiaUser user = (AiaUser) session.getAttribute("user");
        identityService.setAuthenticatedUserId(user.getId().toString());
        Map<String, Object> map = new HashMap<>();
        map.put("userId",user.getId());
        final ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("shoppingProcess",map);
        this.processInstanceId = processInstance.getId();
        return true;
    }

    /**
     * 返回要填写的表单内容
     * @return
     */
    @GetMapping("/taskForm")
    public String taskForm(HttpSession session){
        final AiaUser user = (AiaUser) session.getAttribute("user");
        final Task task = taskService.createTaskQuery().processInstanceId(this.processInstanceId).singleResult();
        if(StringUtils.isEmpty(task.getAssignee())){
            //没有指定人就是发起人
//            final String startUserId = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getStartUserId();
            final Long startUserId = (Long) runtimeService.getVariable(task.getExecutionId(),"userId");
            System.out.println("startUserId:"+startUserId);
            if(user.getId().equals(startUserId)){
                //是本人
                if(StringUtils.isEmpty(task.getFormKey())){
                    return "";
                }else{
                    //TODO 这里还可以再加入流程引擎，允许返回一些特殊的内容，比如之前用户填写个表单数据，也可以是activiti内置的一些变量甚至是系统相关变量

                    final AiaModelForm aiaModelForm = formService.selectById(task.getFormKey());
                    return "<h1>"+task.getName()+"</h1>"+aiaModelForm.getFormContext();
                }
            }else{
                //不是本人
                throw new RuntimeException("你不是发起人，无权操作！");
            }
        }else{
            //有指定人必须是指定的人
            Wrapper wrapper = new EntityWrapper<>();
            wrapper.eq("role",task.getAssignee());
            final Role role = roleService.selectOne(wrapper);
            if(!role.getUserId().equals(user.getId())){
                throw new RuntimeException("你不是被指定人，无权操作！");
            }

            if(StringUtils.isEmpty(task.getFormKey())) {
                return "";
            }else {
                final AiaModelForm aiaModelForm = formService.selectById(task.getFormKey());
                return "<h1>"+task.getName()+"</h1>"+aiaModelForm.getFormContext();
            }

        }
    }

    @GetMapping("/taskFormById")
    public String taskFormById(String taskId){
        final Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        final String formKey = task.getFormKey();
        if(StringUtils.isEmpty(formKey)){
            return "<h1>"+task.getName()+"</h1>";
        }
        System.out.println(formKey);
        final AiaModelForm aiaModelForm = formService.selectById(formKey);
        return "<h1>"+task.getName()+"</h1>"+aiaModelForm.getFormContext();
    }


    @GetMapping("/submitFormById")
    public boolean submitFormById(@RequestParam Map<String,Object> params){
        String taskId = (String) params.get("taskId");
        if(taskId==null){
            throw new RuntimeException("没有指定taskId");
        }
        final Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        Wrapper<AiaModelForm> wrapper = new EntityWrapper<>();
        wrapper.eq("formKey",task.getFormKey());
        final AiaModelForm aiaModelForm = formService.selectOne(wrapper);
        if(aiaModelForm!=null) {
            final String ruleStr = aiaModelForm.getRuleStr();
            System.out.println(ruleStr);

            DroolsStream droolsStream = new DroolsStream();
            droolsStream.setFromKey(task.getFormKey());
            droolsStream.setParams(params);
            DroolsUtil.executeRule(ruleStr, droolsStream);
            System.out.println(ReflectionToStringBuilder.toString(droolsStream));
            if (droolsStream.isError()) {
                throw new RuntimeException(droolsStream.getErrorMsg());
            }
        }
        params.remove(taskId);
        taskService.complete(taskId,params);
        return true;
    }

    @GetMapping("/submitForm")
    public boolean submitForm(@RequestParam Map<String,Object> params){
        //数据应该入库，这里没有做
        final Task task = taskService.createTaskQuery().processInstanceId(this.processInstanceId).singleResult();
        //规则引擎校验
        DroolsStream droolsStream = new DroolsStream();
        droolsStream.setFromKey(task.getFormKey());
        droolsStream.setParams(params);

        Wrapper<AiaModelForm> wrapper = new EntityWrapper<>();
        wrapper.eq("formKey",task.getFormKey());
        final AiaModelForm aiaModelForm = formService.selectOne(wrapper);
        if(aiaModelForm!=null) {
            final String ruleStr = aiaModelForm.getRuleStr();
            System.out.println(ruleStr);
            DroolsUtil.executeRule(ruleStr, droolsStream);
            System.out.println(ReflectionToStringBuilder.toString(droolsStream));
            if (droolsStream.isError()) {
                throw new RuntimeException(droolsStream.getErrorMsg());
            }
        }
        taskService.complete(task.getId(), params);
        return true;
    }


    /**
     * 获取所有的待办任务列表
     * @return
     */
    @GetMapping("/getTasks")
    public List<String> getTasks(HttpSession session){
        List<String> taskIds = new ArrayList<>();

        final AiaUser user = (AiaUser) session.getAttribute("user");
        final Long id = user.getId();


        //获取自己的
        final List<ProcessInstance> processInstances = runtimeService.createProcessInstanceQuery().variableValueEquals("userId", id).list();
        for (ProcessInstance processInstance : processInstances) {
            final Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
            if(StringUtils.isEmpty(task.getAssignee())) {
                taskIds.add(task.getId());
            }
        }
//        final List<Task> tasks = taskService.createTaskQuery().processVariableValueEquals("userId", id).list();
//        for (Task task : tasks) {
//            taskIds.add(task.getId());
//        }


        //获取被指定为自己的
        Wrapper wrapper = new EntityWrapper<>();
        wrapper.eq("userId",id);
        final Role role = roleService.selectOne(wrapper);
        if(role==null){
            return taskIds;
        }
        String roleName = role.getRole();
        final List<Task> list = taskService.createTaskQuery().taskAssignee(roleName).list();

        for (Task task : list) {
            taskIds.add(task.getId());
//            System.out.println(ReflectionToStringBuilder.toString(task));
        }
//        taskService.createTaskQuery().task
        return taskIds;
    }

    @GetMapping("/allTasks")
    public void showAllTask(){
        final List<Task> list = taskService.createTaskQuery().list();
        for (Task task : list) {
            final Object userId = runtimeService.getVariable(task.getExecutionId(), "userId");
            final Map<String, Object> processVariables = task.getProcessVariables();
            final Map<String, Object> taskLocalVariables = task.getTaskLocalVariables();
            System.out.println(ReflectionToStringBuilder.toString(task));
        }
    }


//    @GetMapping("/rule")
//    public void executeRule(){
//        Wrapper<AiaModelForm> wrapper = new EntityWrapper<>();
//        wrapper.eq("formKey","sign");
//        final AiaModelForm aiaModelForm = formService.selectOne(wrapper);
//        final String ruleStr = aiaModelForm.getRuleStr();
//        System.out.println(ruleStr);
//        DroolsUtil.executeRule(ruleStr,new Role());
//    }
}
